package com.yanqu.road.server.gameplayer.module.activity.hell;

import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.hell.CutLawResult;
import com.yanqu.road.entity.activity.hell.HellNpc;
import com.yanqu.road.entity.activity.hell.HellUserData;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.log.LogHellNpc;
import com.yanqu.road.logic.bussiness.activity.HellBusiness;
import com.yanqu.road.pb.activity.HellProto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.manger.activity.hell.HellMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.log.LogMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


public class HellModule extends GeneralModule {

    private HellUserData userData;

    public HellModule(GamePlayer player) {
        super(player);
    }

    public HellUserData getUserData(){
        return userData;
    }

    //新加npc到阎王薄，大于60个就去掉多余的
    private void addNewNpc(Map<Integer, Map<Integer, HellNpc>> allNpc,HellNpc newNpc){
        int npcLimit = HellMgr.getHellNpcLimit();
        if(!allNpc.containsKey(newNpc.getQualityId())){
            allNpc.put(newNpc.getQualityId(),new ConcurrentHashMap<>());
        }
        Map<Integer, HellNpc> qualityNpcMap = allNpc.get(newNpc.getQualityId());
        if(qualityNpcMap.size() >= npcLimit){
            removeOneNpc(qualityNpcMap);
        }
        qualityNpcMap.put(newNpc.getNo(),newNpc);
    }

    private void removeOneNpc(Map<Integer, HellNpc> qualityNpcMap){
        int removeNo = Integer.MAX_VALUE;
        for(int no : qualityNpcMap.keySet()){
            if(no < removeNo){
                removeNo = no;
            }
        }
        if(removeNo != Integer.MAX_VALUE){
            qualityNpcMap.remove(removeNo);
        }
    }

    public Map<Integer, Map<Integer, HellNpc>> getNpcNote(){
        return userData.getNpcMap();
    }

    public CutLawResult cutLaw(int type){
        CutLawResult result = new CutLawResult();
        Property consume = PropertyHelper.parseStringToProperty(HellMgr.getHellSearchCost(type));
        if(!player.getModule(CurrencyModule.class).currencyIsEnough(consume)){
            result.setRet(GameErrorCode.E_BAG_ITEM_NO_ENOUGH);
            return result;
        }
        player.getModule(CurrencyModule.class).removeCurrency(consume, eLogMoneyType.HellActivity,eLogMoneyType.HellActivityCutLaw);
        long reward = 0;
        List<HellNpc> npcList =  HellMgr.hellCutLaw(type);
        int npcCount = userData.getNpcCount();
        Map<Integer, Map<Integer, HellNpc>> allNpc = userData.getNpcMap();
        for(HellNpc npc : npcList){
            npc.setNo(++npcCount);
            addNewNpc(allNpc,npc);
            int addReward = HellMgr.getQualityReward(npc.getQualityId());
            reward += addReward;
            LogMgr.addLogHellNpc(new LogHellNpc(userData.getActivityId(),userData.getUserId(),npc.getNo(),npc.getNpcId(),npc.getQualityId(),npc.getAgeId(),
                    npc.getEventMap(),addReward,System.currentTimeMillis()));
        }
        player.getModule(CurrencyModule.class).addCurrency(HellMgr.getHellScoreItemId() + "=" + reward,eLogMoneyType.HellActivity,eLogMoneyType.HellActivityCutLaw);
        player.notifyListener(eGamePlayerEventType.HellActivityScoreRank.getValue(),userData.getIntegral() + reward);
        player.notifyListener(eGamePlayerEventType.HellActivityScoreCrossRank.getValue(),userData.getIntegral() + reward);
        player.notifyListener(eGamePlayerEventType.HellActivityScore.getValue(),userData.getIntegral() + reward);
        userData.setIntegral(userData.getIntegral() + reward);
        userData.setNpcCount(npcCount);
        userData.setNpcMap(allNpc);
        result.setNpcList(npcList);

        result.setIntegral(userData.getIntegral());
        return result;
    }

    @Override
    public boolean loadData() {
        if(SystemOpenMgr.systemOpen(player, eSystemId.HellActivity.getValue())){
            ActivityInfo activityInfo = HellMgr.getActivityInfo();
            if(activityInfo != null){
                userData = HellBusiness.getUserData(getUserId(),activityInfo.getActivityId());
                if(userData == null){
                    initUserData(activityInfo.getActivityId());
                }
            }
        }
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return false;
    }

    @Override
    public boolean saveData() {
        if(userData != null){
            if(userData.isInsertOption()){
                HellBusiness.addHellUserData(userData);
            }else if(userData.isUpdateOption()){
                HellBusiness.updateHellUserData(userData);
            }
        }
        return true;
    }

    @Override
    public void afterLogin() {
        if(SystemOpenMgr.systemOpen(player, eSystemId.HellActivity.getValue())){
            ActivityInfo activityInfo = HellMgr.getActivityInfo();
            if(activityInfo != null){
                syncUserData();
            }
        }
    }

    public void syncUserData(){
        HellProto.HellDataSyncMsg.Builder syncMsg = HellProto.HellDataSyncMsg.newBuilder();
        syncMsg.setActivityId(HellMgr.getShowTimeActivityId());
        syncMsg.setIntegral(userData.getIntegral());
        syncMsg.setConfigData(HellMgr.getConfigDataTempBuilder(player.getLanguage()));
        player.sendPacket(Protocol.U_HELL_DATA_SYNC, syncMsg);
    }

    public void initUserData(int activityId){
        if(userData == null || userData.getActivityId() != activityId){
            HellUserData tempUserData = new HellUserData();
            tempUserData.setActivityId(activityId);
            tempUserData.setUserId(getUserId());
            tempUserData.setIntegral(0);
            tempUserData.setNpcCount(0);
            tempUserData.setUpdateTime(System.currentTimeMillis());
            tempUserData.setInsertOption();
            userData = tempUserData;
        }
    }

    /**
     * 系统解锁
     */
    public void initSystem() {
        ActivityInfo activityInfo = HellMgr.getActivityInfo();
        if(activityInfo != null){
            initUserData(activityInfo.getActivityId());
            syncUserData();
        }
    }

}
